package com.ruoyi.AesUtil;

/**
 * @author jitwxs
 * @date 2023年12月10日 21:51
 */

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.mqttClient.AutoSendMsgMqttCallback;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.security.*;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

@Service("aESUtil")
public class AESUtil {
    private static final Logger logger = LoggerFactory.getLogger(AESUtil.class);
    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法
    private static final String password = "keson-123";

    private static final String NoPadding_CIPHER_ALGORITHM = "AES/ECB/NoPadding";//默认的加密算法
    private static final String NoPaddingpassword = "keson-123abcdefg";
    public static final String ECB_PKCS7_PWD = "Keson123456789101112131415161718";
    public static final String ECB_PKCS7_VI = "82827196kesonabc";
    static {
        // PKCS7扩展
        Security.addProvider(new BouncyCastleProvider());
    }
    /**
     * AES 加密操作
     *
     * @param content 待加密内容
     * @param
     * @return 返回Base64转码后的加密数据
     */
    /*public static String encrypt(String content) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器

            byte[] byteContent = content.getBytes("UTF-8");

            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器

            byte[] result = cipher.doFinal(byteContent);// 加密
            return new String(Base64.getEncoder().encode(result),"UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }*/

    public String encryptNoPadding(String content) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

            byte[] byteContent = content.getBytes("UTF-8");

            SecretKeySpec securekey = new SecretKeySpec(NoPaddingpassword.getBytes(), "AES");//设置加密Key
            cipher.init(Cipher.ENCRYPT_MODE, securekey);//设置密钥和解密形式

            return new String(Base64.getEncoder().encode(cipher.doFinal(byteContent)),"UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * AES 解密操作
     *
     * @param content
     * @param
     * @return
     */
    public static String decrypt(byte[] content) {
        String result = decryptNoPadding(content);
        if(result==null) {
            return decryptPKCS5Padding(content);
        }else {
            return result;
        }
    }

    private static String decryptPKCS5Padding(byte[] content) {

        try {
            content = Base64.getDecoder().decode(new String(content,"UTF-8"));
            //瀹炰緥鍖�
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

            //返回生成指定算法密钥生成器的 KeyGenerator 对象
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));

            //解密
            byte[] result = cipher.doFinal(content);

            return new String(result, "UTF-8");
        } catch (Exception ex) {
            logger.info("解密消息", "PKCS5Padding解密失败");
            return null;
        }
    }



    private static String decryptNoPadding(byte[] content) {
        try {
            content = Base64.getDecoder().decode(new String(content,"UTF-8"));

            Cipher cipher = Cipher.getInstance(NoPadding_CIPHER_ALGORITHM);
            SecretKeySpec securekey = new SecretKeySpec(NoPaddingpassword.getBytes(), "AES");//设置加密Key
            cipher.init(Cipher.DECRYPT_MODE, securekey);//设置密钥和解密形式

            return new String(cipher.doFinal(content), "UTF-8");
        } catch (Exception ex) {
            logger.info("解密消息", "NoPadding解密失败");
            return null;
        }
    }

    /**
     * 生成加密秘钥
     *
     * @return
     */
    private static SecretKeySpec getSecretKey(final String password) {
        //返回生成指定算法密钥生成器的 KeyGenerator 对象
        KeyGenerator kg = null;

        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);

            //AES 要求密钥长度为 128

            SecureRandom random=null;
            try {
                random = SecureRandom.getInstance("SHA1PRNG","SUN");
                random.setSeed(password.getBytes());
            } catch (NoSuchProviderException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            kg.init(128, random);

            //生成一个密钥
            SecretKey secretKey = kg.generateKey();

            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public static String decrypt(String content, String key, String vi) {

        try{
            Key k = toKey(key.getBytes());
            byte[] encoded = k.getEncoded();
            SecretKeySpec aes = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            IvParameterSpec iv = new IvParameterSpec(vi.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, aes, iv);

            byte[] bytes = cipher.doFinal(org.apache.tomcat.util.codec.binary.Base64.decodeBase64(content));

            return new String(bytes, "UTF-8");
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    public static String encryptCBC_PKCS7(String content, String key, String vi) {

        try{
            //Key k = toKey(Base64.decodeBase64(key));
            Key k = toKey(key.getBytes());
            byte[] encoded = k.getEncoded();
            SecretKeySpec aes = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            IvParameterSpec iv = new IvParameterSpec(vi.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, aes, iv);
            byte[] bytes = cipher.doFinal(content.getBytes("UTF-8"));
            return org.apache.tomcat.util.codec.binary.Base64.encodeBase64String(bytes);
        } catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    private static Key toKey(byte[] key){
        SecretKeySpec aes = new SecretKeySpec(key, "AES");
        return aes;
    }

    public static void main(String[] args) {
        //System.out.println(encrypt("{\"11\":7.0,\"12\":4,\"13\":\"SC\",\"14\":0.69,\"1\":1,\"2\":1,\"3\":504,\"4\":0,\"5\":1560908160,\"6\":13,\"7\":104.77,\"8\":28.42,\"9\":0,\"10\":6}"));
        JSONObject textContent = new JSONObject();
        textContent.put("deviceNo", "892358432652");
        textContent.put("deptName", "山东省地震局");
//        String text = "{\"deviceNo\":\"892358432652\",\"deptName\":\"山东省地震局\"}";
        String text = "{\"deptName\":\"山东省地震局\",\"deviceNo\":\"892358432652\"}";
        System.out.println(text);
        System.out.println(textContent.toJSONString());
        System.out.println(encryptCBC_PKCS7(text, ECB_PKCS7_PWD, ECB_PKCS7_VI));
        System.out.println(encryptCBC_PKCS7(textContent.toJSONString(), ECB_PKCS7_PWD, ECB_PKCS7_VI));
        // System.out.println(decryptNoPadding("056DdU1qsvPfCI0TeH+wztzAj4MnAT3BJ+cACASSLnLIbZcfwtA/6myFdneUl/T9+qEw56z4nfc9Z3mefWiSjkaUqAxmXcMqXoUVXJHNvkw=".getBytes()));
    }
}
